/*
* Copyright © Shanghai Awinic Technology Co., Ltd. 2020-2020. All rights reserved.
* Description: TIMER driver related library function files.
* Date： 20201126
* Awinic_Version： aw_soc_driver_v1.0.0
*/
#include "compile_option.h"
#ifdef AW_86802

#include "aw8680x_global.h"

/**
  * @brief  Timer clean interrupt function
  * @param  p_instance_s pointer to a TIMER_TYPE_S structure that contains
  *             the register information for the specified TIMER.
  * @retval RET_STATUS_E status
  */
static RET_STATUS_E timer_clean_mask(TIMER_TYPE_S *p_instance_s)
{
	__IO AW_U32 temp_flag = AW_NUM_NULL;

	/* Check the TIMER handle allocation. */
	if (p_instance_s == AW_NULL) {
		return RET_ERROR;
	}

	temp_flag = p_instance_s->EOI;

	return RET_OK;
}

/**
  * @brief  TIMER interrupt number configuration function
  * @param  TIMER pointer to a TIMER_HANDLE_TYPE_S structure that contains
  *               the configuration information for the specified TIMER.
  * @retval RET_STATUS_E status
  */
static RET_STATUS_E timer_irq_config(TIMER_HANDLE_TYPE_S *p_timer_lib)
{
	/* Check the TIMER handle allocation. */
	if (p_timer_lib == AW_NULL) {
		return RET_ERROR;
	}

	NVIC_EnableIRQ(p_timer_lib->timer_irq_e); //  Enable Interrupt.
	NVIC_SetPriority(p_timer_lib->timer_irq_e, p_timer_lib->timer_irq_pri_e); // Set Interrupt Priority.

	return RET_OK;
}

/**
  * @brief  TIMER enable function
  * @param  TIMER pointer to a TIMER_HANDLE_TYPE_S structure that contains
  *               the configuration information for the specified TIMER
  * @retval RET_STATUS_E status
  */
RET_STATUS_E timer_enable(TIMER_HANDLE_TYPE_S *p_timer_lib)
{
	/* Check the TIMER handle allocation. */
	if (p_timer_lib == AW_NULL) {
		return RET_ERROR;
	}

	p_timer_lib->p_instance_s->CR |= TIME_EN;

	return RET_OK;
}

/**
  * @brief  TIMER disable function
  * @param  TIMER pointer to a TIMER_HANDLE_TYPE_S structure that contains
  *               the configuration information for the specified TIMER
  * @retval RET_STATUS_E status
  */
RET_STATUS_E timer_disable(TIMER_HANDLE_TYPE_S *p_timer_lib)
{
	/* Check the TIMER handle allocation. */
	if (p_timer_lib == AW_NULL) {
		return RET_ERROR;
	}

	p_timer_lib->p_instance_s->CR &= TIME_DIS;

	return RET_OK;
}

/**
  * @brief  TIMER initialization function
  * @param  TIMER pointer to a TIMER_HANDLE_TYPE_S structure that contains
  *               the configuration information for the specified TIMER.
  * @retval RET_STATUS_E status
  */
RET_STATUS_E timer_init(TIMER_HANDLE_TYPE_S *p_timer_lib)
{
	/* Check the TIMER handle allocation. */
	if (p_timer_lib == AW_NULL) {
		return RET_ERROR;
	}

	/* Check the parameters. */
	assert_param(TIMER_CHECK_INSTANCE(p_timer_lib->p_instance_s));
	assert_param(TIMER_CHECK_MODE(p_timer_lib->init_s.timer_mode));

	/* Clear the existing interruption. */
	timer_clean_mask(p_timer_lib->p_instance_s);

	/* Set timer clk */
	if (p_timer_lib->p_instance_s == TIMER0) {
		timer0_clk_init();
	} else if (p_timer_lib->p_instance_s == TIMER1) {
		timer1_clk_init();
	}

	/* Set timer interrupt number. */
	timer_irq_config(p_timer_lib);

	if (p_timer_lib->init_s.timer_mode == TIME_USER_MODE) {
		p_timer_lib->p_instance_s->LC = p_timer_lib->init_s.timer_load_count;
		p_timer_lib->p_instance_s->CR &= TIME_DIS;
		p_timer_lib->p_instance_s->CR &= TIME_MASK_DIS;
		p_timer_lib->p_instance_s->CR |= p_timer_lib->init_s.timer_mode;
		p_timer_lib->p_instance_s->CR |= TIME_EN;
	} else {
		p_timer_lib->p_instance_s->CR &= TIME_DIS;
		p_timer_lib->p_instance_s->CR &= TIME_MASK_DIS;
		p_timer_lib->p_instance_s->CR &= p_timer_lib->init_s.timer_mode;
		p_timer_lib->p_instance_s->CR |= TIME_EN;
	}

	return RET_OK;
}

/**
  * @brief  set timer load cnt fun
  * @param  TIMER_TYPE_S *tim, AW_U32 load_cnt
  * @retval RET_STATUS_E status
  */
RET_STATUS_E timer_set_load_cnt(TIMER_TYPE_S *p_tim, AW_U32 load_cnt)
{
	/* Check the TIMER handle allocation. */
	if (p_tim == AW_NULL) {
		return RET_ERROR;
	}

	/* time = load_cnt / 24M */
	p_tim->LC = load_cnt;
	return RET_OK;
}

/**
  * @brief  Timer callback function
  * @param  TIMER pointer to a TIMER_HANDLE_TYPE_S structure that contains
  *            the configuration information for the specified TIMER.
  * @retval None
  */
__weak void timer0_irq_call(TIMER_HANDLE_TYPE_S *p_timer_lib)
{
	/* Prevent unused argument(s) compilation warning. */
	assert_param(p_timer_lib);

	/* NOTE : This function Should not be modified, when the callback is needed,
			the aw_lib_timer_call could be implemented in the user file
	*/
}

/**
  * @brief  Timer callback function
  * @param  TIMER pointer to a TIMER_HANDLE_TYPE_S structure that contains
  *         the configuration information for the specified TIMER.
  * @retval None
  */
__weak void timer1_irq_call(TIMER_HANDLE_TYPE_S *p_timer_lib)
{
	/* Prevent unused argument(s) compilation warning. */
	assert_param(p_timer_lib);

	/* NOTE : This function Should not be modified, when the callback is needed,
			the aw_lib_timer_call could be implemented in the user file
	*/
}

/**
  * @brief  TIMER interrupt receive function
  * @param  TIMER pointer to a TIMER_HANDLE_TYPE_S structure that contains
  *         the configuration information for the specified TIMER.
  * @retval RET_STATUS_E status
  */
RET_STATUS_E timer_irq(TIMER_HANDLE_TYPE_S *p_timer_lib)
{
	/* Check the TIMER handle allocation. */
	if (p_timer_lib == AW_NULL) {
		return RET_ERROR;
	}

	if (p_timer_lib->p_instance_s == TIMER0) {
		/* Add user's timer service function. */
		timer0_irq_call(p_timer_lib);
	}

	if (p_timer_lib->p_instance_s == TIMER1) {
		/* Add user's timer service function. */
		timer1_irq_call(p_timer_lib);
	}

	/* Clear the existing interruption */
	timer_clean_mask(p_timer_lib->p_instance_s);

	return RET_OK;
}
#endif
